package com.colabo.j2ee.web.core.log;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.ThrowsAdvice;

import com.colabo.j2ee.web.core.common.CommonConstants;
import com.colabo.j2ee.web.core.exception.ExceptionStatistics;
import com.colabo.j2ee.web.core.util.PropertyUtil;

/**
 * 通过AOP方式进行异常拦截，主动在使用人员不知晓情况下记录异常日志，如ServiceException,CommonException等CheckedException<br>
 * 使用方法：<br>
 * 1：首先在xml配置文件中声明advise <br>
 * &lt;bean id="logthrow" class="com.cib.cap.base.common.log.LogThrowAdvice"/&gt;<br>
 * 2:然后在xml配置文件中设置拦截的模式<br>
 *  &lt;aop:config &gt; <br>
 *  &lt;aop:pointcut id="serviceOperation" expression="execution(* com.cib.cap..*Service.*(..))"/&gt;<br>
 * 		&lt;aop:advisor pointcut-ref="serviceOperation" advice-ref="logthrow" /&gt;<br>
 * &/aop:config&gt; <br>
 * 3:采用advisor方式，可以让log拦截和其它拦截器一起工作而互相不受干扰<br>
 */
public class LogThrowAdvice implements ThrowsAdvice, Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Log logger = LogFactory.getLog(LogThrowAdvice.class);

	/**
	 * target的参数用来拦截后的控制，比如判断 target instanceof xxInterface
	 */
	public void afterThrowing(Method method, Object[] args, Object target, Throwable subclass) {
		// 异常跟踪信息显示
		// 1:自己遍历异常堆栈信息
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < subclass.getStackTrace().length; i++) {
			StackTraceElement ste = (StackTraceElement) subclass.getStackTrace()[i];
			sb.append(ste.toString() + "\n");
		}

		// 2:采用ExceptionStatistics的异常信息统计
		ExceptionStatistics es = new ExceptionStatistics();
		es.setTraceEnabled(true);
		es.updateStatistics(subclass, method.getName(), target.getClass().getName(), new Date());
		String xml = es.toXML();
		es.reset();
		logger.error(PropertyUtil.getPropertyByKey(CommonConstants.MSG_LOG_EXCEPTION, new String[] {
				target.getClass().getName(), method.getName(), subclass.toString(), xml }));
	}
}
